package com.jp.juc.taskFrame.context;

import cn.hutool.core.util.ObjectUtil;
import com.jp.juc.taskFrame.domain.vo.*;

import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ThreadPoolExecutor;

/**
 * 框架的主体类，也是调用者主要使用的类
 */
public class PendingJobPool {


    private ThreadPoolExecutor taskExecutor;

    public PendingJobPool(ThreadPoolExecutor taskExecutor) {
        this.taskExecutor = taskExecutor;
    }

    /*工作信息的存放容器*/
    private static ConcurrentHashMap<String, JobInfo<?>> jobInfoMap
            = new ConcurrentHashMap<>();


    public static Map<String, JobInfo<?>> getMap() {
        return jobInfoMap;
    }


    private static class PendingTask<T, R> implements Runnable {

        private JobInfo<R> jobInfo;
        private T processData;

        public PendingTask(JobInfo<R> jobInfo, T processData) {
            this.jobInfo = jobInfo;
            this.processData = processData;
        }

        @Override
        public void run() {
            TaskProcess<T, R> taskProcess = (TaskProcess<T, R>) jobInfo.getTaskProcess();
            TaskResult<R> result = null;
            try {
                result = taskProcess.taskExecute(processData);
                if (result == null) {
                    result = new TaskResult<>(TaskResultType.Exception, null, "result is null");
                }
                if (result.getResultType() == null) {
                    if (result.getReason() == null) {
                        result = new TaskResult<>(TaskResultType.Exception, null, "result is null");
                    } else {
                        result = new TaskResult<>(TaskResultType.Exception, null, "result is null,reason:" + result.getReason());
                    }
                }
            } catch (Exception e) {
                e.printStackTrace();
                result = new TaskResult<>(TaskResultType.Exception, null, e.getMessage());
            } finally {
                jobInfo.addTaskResult(result);
            }
        }
    }

    public <R> void registerJob(String jobName, int jobLength, TaskProcess<?, ?> taskProcess, long expireTime) {
        JobInfo<R> jobInfo = new JobInfo<>(jobName, jobLength, taskProcess, expireTime);

        if (ObjectUtil.isNotEmpty(jobInfoMap.putIfAbsent(jobName, jobInfo))) {
            throw new RuntimeException(jobName + "已经注册！");
        }
    }

    //调用者提交工作中的任务
    public <T, R> void putTask(String jobName, T t) {
        JobInfo<R> jobInfo = getJob(jobName);
        PendingTask<T, R> task = new PendingTask<>(jobInfo, t);
        taskExecutor.execute(task);
    }

    /*根据工作名称检索工作*/
    @SuppressWarnings("unchecked")
    private <R> JobInfo<R> getJob(String jobName) {
        JobInfo<R> jobInfo = (JobInfo<R>) jobInfoMap.get(jobName);
        if (null == jobInfo)
            throw new RuntimeException(jobName + "是非法任务！");
        return jobInfo;
    }

    /*获得工作的整体处理进度*/
    public <R> TotalProcess getTaskProcess(String jobName) {
        JobInfo<R> job = getJob(jobName);
        return job.getTotalProcessObj();
    }

    /*获得每个任务的处理详情*/
    public <R> List<TaskResult<R>> getTaskDetail(String jobName) {
        JobInfo<R> job = getJob(jobName);
        return job.getTaskDetail();
    }

}
